package com.uziot.bucket.common.concurrent.juc;

import com.uziot.bucket.common.pool.ThreadPoolFactory;

import java.util.concurrent.Semaphore;

/**
 * @author shidt
 * @version V1.0
 * @className SemaphoreDemo
 * @date 2021-03-29 21:38:19
 * @description 对信号量的简单DEMO
 */

public class SemaphoreDemo {
    public static void main(String[] args) {
        PrintQueue printQueue = new PrintQueue();
        for (int i = 0; i < 10; i++) {
            ThreadPoolFactory.threadPoolTaskExecutor().submit(new Job(printQueue));
        }
    }

}

class PrintQueue {
    private final Semaphore semaphore;

    /**
     * 这是一个二进制信号量哦，计数器值只能是0或者1；
     */
    public PrintQueue() {
        semaphore = new Semaphore(1);
    }

    public void printJob(Object document) {
        try {
            //获取共享资源，如果计数器为0会等待
            semaphore.acquire();
            long duration = (long) (Math.random() * 10);
            System.out.printf("%s: PrintQueue: Printing a job during %d seconds \n", Thread.currentThread().getName(), duration);
            Thread.sleep(duration);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            //放在finally语句块表示不管发不发生异常都会执行，都会释放资源。
            semaphore.release();
        }
    }
}

class Job implements Runnable {
    private final PrintQueue printQueue;

    public Job(PrintQueue printQueue) {
        this.printQueue = printQueue;
    }

    @Override
    public void run() {
        System.out.printf("%s: Going to print a job\n", Thread.currentThread().getName());
        printQueue.printJob(new Object());
        System.out.printf("%s: The document has been printed\n", Thread.currentThread().getName());
    }
}